﻿using System;
using System.IO;
using System.Windows;
using OSGeo.GDAL;

namespace GPVC
{
    class RasterIO
    {
        public struct GeoTiffInfo
        {
            public string fileName;
            public Dataset dataset;
            public int bandCount;
            public int height;
            public int width;
            public double[] spatialResolution;
            public double[] transform;
            public bool hasPCS;
            public OSGeo.OSR.SpatialReference gcs;
            public OSGeo.OSR.SpatialReference pcs;
            public int errInfo;
        }

        private static GeoTiffInfo geoTiffInfo;

        private static Dataset OpenGeoTiff(string filePath)
        {
            GdalConfiguration.ConfigureGdal();

            Gdal.AllRegister();
            //
            Dataset dataset = null;
            try
            {
                dataset = Gdal.Open(filePath, Access.GA_ReadOnly);
            }
            catch (Exception errInfo)
            {
                MessageBox.Show(errInfo.Message, "错误信息", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            return dataset;
        }

        public static GeoTiffInfo GetGeoTiffInfo(string filePath)
        {
            var dataset = OpenGeoTiff(filePath);
            //
            double[] geoTransform = new double[6];
            OSGeo.OSR.SpatialReference pcs = new OSGeo.OSR.SpatialReference(null);
            OSGeo.OSR.SpatialReference gcs = new OSGeo.OSR.SpatialReference(null);
            //
            dataset.GetGeoTransform(geoTransform);
            double[] spatialResolution = { geoTransform[1], -1.0 * geoTransform[5] };
            string pcsStr = dataset.GetProjection();
            pcs.ImportFromWkt(ref pcsStr);
            gcs = pcs.CloneGeogCS();
            //
            if (pcs.IsProjected() == 1 && gcs.IsGeographic() == 1) geoTiffInfo.hasPCS = true;
            if (pcs.IsProjected() != 1 && gcs.IsGeographic() != 1) geoTiffInfo.hasPCS = false;
            //
            geoTiffInfo.fileName = Path.GetFileName(filePath);
            geoTiffInfo.dataset = dataset;
            geoTiffInfo.bandCount = dataset.RasterCount;
            geoTiffInfo.height = dataset.RasterYSize;
            geoTiffInfo.width = dataset.RasterXSize;
            geoTiffInfo.spatialResolution = spatialResolution;
            geoTiffInfo.transform = geoTransform;
            geoTiffInfo.gcs = gcs;
            geoTiffInfo.pcs = pcs;
            //
            if(pcs.IsProjected() != 1 && pcs.IsGeographic() != 1) geoTiffInfo.errInfo = 0;
            else geoTiffInfo.errInfo = 1;
            //
            return geoTiffInfo;
        }

        public static double[] ReadGeoTiff(string filePath, int bandIndex)
        {
            var dataset = OpenGeoTiff(filePath);
            //
            var width = dataset.RasterXSize;
            var height = dataset.RasterYSize;
            var xOff = 0;
            var yOff = 0;
            //
            var bandArr = new double[height * width];
            try
            {
                var band = geoTiffInfo.dataset.GetRasterBand(bandIndex);
                var cPLErr = band.ReadRaster(xOff, yOff, width, height, bandArr, width, height, 0, 0);
            }
            catch (Exception errInfo)
            {
                MessageBox.Show(errInfo.Message, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            //
            return bandArr;
        }

        public static double[] ReadGeoTiff(GeoTiffInfo geoTiffInfo, int bandIndex)
        {
            var width = geoTiffInfo.width;
            var height = geoTiffInfo.height;
            var xOff = 0;
            var yOff = 0;
            //
            var bandArr = new double[height * width];
            try
            {
                var band = geoTiffInfo.dataset.GetRasterBand(bandIndex);
                var cPLErr = band.ReadRaster(xOff, yOff, width, height, bandArr, width, height, 0, 0);
            }
            catch (Exception errInfo)
            {
                MessageBox.Show(errInfo.Message, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            //
            return bandArr;
        }

    }
}
